package com.bee.common.tools.web;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class WebClient {
    
    private static final String DEFAULT_CHARSET = "UTF-8";
    
	private static Logger logger = LoggerFactory.getLogger(WebClient.class);

	private static ObjectMapper objectMapper = new ObjectMapper();
	
	private static JsonNode execute(HttpUriRequest req){
		HttpClient httpClient = new DefaultHttpClient();
		JsonNode result = null;
		try {
			logger.info("[{}] - {} ", 
					new Object[]{req.getMethod(), req.getURI().toString()});
			HttpResponse response = httpClient.execute(req);
			logger.info("request url :" + req.getURI().toString() + ", response code :" + response.getStatusLine().getStatusCode());
			result = objectMapper.readTree(EntityUtils.toString(response.getEntity(),"UTF-8"));
			if(result.has("errcode") &&  0 != result.get("errcode").asInt()){
				logger.info("request url is : {}",req.getURI().toString());
				logger.info("Return Http Code : {} - {}", result.get("errcode").asText()
						, result.get("errmsg").asText());	
			}
		} catch (ClientProtocolException e) {
			logger.error("http protocol is error",e);
		} catch (IOException e) {
			logger.error("io is error",e);
		}
		return result;
	}
	
	public static JsonNode get(String url) {
		HttpGet method = new HttpGet(url);
		return execute(method);
	}
	
	public static JsonNode post(String url, String params, Map<String,String> header){
		HttpPost method = new HttpPost(url);
		try {
			method.setEntity(new StringEntity(params,"UTF-8"));
			for(Entry<String,String> entry : header.entrySet()){
				method.setHeader(entry.getKey(), entry.getValue());
			}
		} catch (Exception e) {
			logger.error("Error when post msg to WeChat", e);
		}
		return execute(method);
	}
	
	public static JsonNode post(String url,String params){
		HttpPost method = new HttpPost(url);
		try {
			method.setEntity(new StringEntity(params,"UTF-8"));
		} catch (Exception e) {
			logger.error("Error when post msg to WeChat", e);
		}
		return execute(method);
	}
	
	public static JsonNode get(String url, Map<String, String> params) {
		HttpGet method = new HttpGet(initParams(url,params));
		return execute(method);
	}
	
	/**
     * 构造url
     * @param url
     * @param params
     * @return
     */
    public static String initParams(String url, Map<String, String> params){
        if (null == params || params.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder(url);
        if (url.indexOf("?") == -1) {
            sb.append("?");
        } else {
            sb.append("&");
        }
        boolean first = true;
        for (Entry<String, String> entry : params.entrySet()) {
            if (first) {
                first = false;
            } else {
                sb.append("&");
            }
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key).append("=");
            if (!StringUtils.isEmpty(value)) {
                try {
                    sb.append(URLEncoder.encode(value, DEFAULT_CHARSET));
                } catch (UnsupportedEncodingException e) {
                    logger.error(url,e);
                }
            }
        }
        return sb.toString();
    }
    
    public static ByteArrayOutputStream downUrlTxt(String fileUrl){
    	 ByteArrayOutputStream oputstream = null;
	      try {  
	    	  oputstream = new ByteArrayOutputStream();
	          URL url = new URL(fileUrl);  
	          HttpURLConnection uc = (HttpURLConnection) url.openConnection();  
	          uc.setDoInput(true);//设置是否要从 URL 连接读取数据,默认为true  
	          uc.connect();  
	          if(uc.getContentLength() == 0){
	        	  return oputstream;
	          }
	          InputStream iputstream = uc.getInputStream();  
	          byte[] buffer = new byte[4*1024];  
	          int byteRead = -1;     
	          while((byteRead=(iputstream.read(buffer)))!= -1){  
	              oputstream.write(buffer, 0, byteRead);  
	          }  
	          iputstream.close();  
	      } catch (Exception e) {  
	    	  logger.error(fileUrl,e);
	      }      
	      return oputstream;
	}

	public static InputStream getInputStream(String url) throws ClientProtocolException, IOException {
		HttpClient client = new DefaultHttpClient();
		HttpGet get = new HttpGet(url);
		HttpResponse response = client.execute(get);
		int statusCode = response.getStatusLine().getStatusCode();
		if(statusCode ==200){
			return response.getEntity().getContent();
		}
		return null;
	}
	
	public static String getResult(String urlStr, String content, String charset)
			throws Exception {
		URL url = null;
		String line = null;
		HttpURLConnection connection = null;
		try {
			url = new URL(urlStr);
			connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.connect();
			DataOutputStream out = new DataOutputStream(
					connection.getOutputStream());
			if (charset != null)
				out.write(content.getBytes(charset)); // 用utf-8的编码方式传递参数，否则中文会出现乱码
			out.write(content.getBytes());
			out.flush();
			out.close();

			try {
				ByteArrayOutputStream outStream = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = connection.getInputStream().read(buffer)) != -1) {
					outStream.write(buffer, 0, len);
				}
				byte[] data = outStream.toByteArray();
				line = new String(data, "UTF-8");
			} catch (Exception e) {
				logger.error("错误消息", e);
			}
		} catch (IOException e) {
			logger.error("错误消息", e);
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
		}
		return line;

	}

}
